package com.zhejiangzhengyuan.municipal_common.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhejiangzhengyuan.municipal_common.entity.Device;
import com.zhejiangzhengyuan.municipal_common.entity.DevicePo;
import com.zhejiangzhengyuan.municipal_common.entity.vo.DeviceVo;
import com.zhejiangzhengyuan.municipal_common.mapper.DeviceMapper;
import com.zhejiangzhengyuan.municipal_common.mapper.ElectronicDataMapper;
import com.zhejiangzhengyuan.municipal_common.response.ResponseVo;
import com.zhejiangzhengyuan.municipal_common.service.DeviceService;
import com.zhejiangzhengyuan.municipal_common.utils.ConstantUtil;
import com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil;
import com.zhejiangzhengyuan.municipal_common.utils.LED.URLUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.List;

import static com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil.getStringByTime;
import static com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil.timeFormat;

/**
 * 物联网设备表，用于存储物联网监测设备数据 服务实现类
 *
 * @author linju
 * @since 2019-11-22
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {

  @Autowired private DeviceMapper deviceMapper;

  @Autowired private ElectronicDataMapper electronicDataMapper;

  @Autowired private URLUtils urlUtils;

  /**
   * 新建设备
   *
   * @param device 设备
   */
  @Transactional(rollbackFor = Exception.class)
  @Override
  public ResponseVo saveDevice(Device device) {
    device.setStatus("在线");
    device.setWarn(false);
    return duplicatedCodeInsertDevice(device);
  }

  /**
   * 更新设备
   *
   * @param device 设备
   */
  @Transactional(rollbackFor = Exception.class)
  @Override
  public int updateDevice(Device device) {
    // 设置设备的更新时间
    device.setUpdateTime(timeFormat(System.currentTimeMillis()));
    // longitude,latitude
    String[] split = device.getGeometry().split(",");
    // 设备的Geo 后续修改
    device.setGeometry(null);
    if (deviceMapper.updateById(device) > 0) {
      // 更新成功后修改geometry
      return deviceMapper.updateGeometry(device.getId(), split[0], split[1]);
    }
    return 0;
  }

  @Override
  public void updateGeoByName(DevicePo device) {
    deviceMapper.updateGeoByName(
        device.getName(),
        device.getGeomDes(),
        device.getGeophysicalPeriod(),
        device.getX(),
        device.getY());
  }

  /** 实时监控查询设备的列表 */
  @Override
  public List<DeviceVo> getDeviceAndFacility(String deviceType) {
    return deviceMapper.selectWarnDevice(deviceType);
  }

  /** 信息维护里面的查询设备与设施的关联 */
  @Override
  public Page<DeviceVo> selectAllDevice(Page<DeviceVo> page, String deviceType) {
    return deviceMapper.selectAllDevice(page, deviceType);
  }

  @Override
  public ResponseVo selectWarnProblemsCharts(int month) {
    // 获取当前年份
    String year = DateFormatUtil.getStringByTime("yyyy", System.currentTimeMillis());
    // 匹配日期
    JSONObject object = new JSONObject();
    // 找到每一天的告警次数
    object.put("warnCountCharts", formatWarnCharts(year, month));
    // 积水报警次数柱状图
    String date = year + "-" + (month < 10 ? "0" + month : month);
    object.put("deviceCharts", formatDeviceWarnCharts(date));
    return ResponseVo.successWithData(object);
  }

  @Override
  public ResponseVo getWaterValueByDeviceCode(String deviceCode) {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE, -1);
    String startTime;
    String endTime;
    long nextTime = calendar.getTimeInMillis();
    JSONArray array = new JSONArray();
    for (int i = 1; i <= 12; i++) {
      startTime = DateFormatUtil.getStringByTime("yyyy-MM-dd HH:mm:ss", nextTime);
      // 时间间隔两小时
      calendar.add(Calendar.HOUR_OF_DAY, 2);
      nextTime = calendar.getTimeInMillis();
      endTime = DateFormatUtil.getStringByTime("yyyy-MM-dd HH:mm:ss", nextTime - 1);

      Integer waterValueByDeviceCode =
          electronicDataMapper.getWaterValueByDeviceCode(deviceCode, startTime, endTime);
      JSONObject object = new JSONObject();
      object.put("x", i * 2);
      object.put("y", waterValueByDeviceCode == null ? 0 : waterValueByDeviceCode);
      array.add(object);
    }
    return ResponseVo.successWithData(array);
  }

  // 设备积水柱状图
  private JSONArray formatDeviceWarnCharts(String date) {
    QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("type", ConstantUtil.DEVICE_TYPE.FLOODED_ROAD).like("name", "水尺");
    List<Device> devices = deviceMapper.selectList(queryWrapper);
    // 根据设备找到指定值
    JSONArray result = new JSONArray();
    for (Device device : devices) {
      JSONObject object = new JSONObject();
      object.put("name", device.getName());
      object.put("value", deviceMapper.selectCountByDeviceId(device.getId(), date));
      result.add(object);
    }
    return result;
  }

  // 系统告警折线图
  private JSONArray formatWarnCharts(String year, int month) {
    String hourPattern = "yyyy-MM-dd HH:mm:ss";
    // 根据找到月份
    Calendar calendar = Calendar.getInstance();
    calendar.clear();
    calendar.set(Calendar.MONTH, month - 1);
    calendar.set(Calendar.YEAR, Integer.parseInt(year));
    JSONArray result = new JSONArray();
    for (int i = 1; i <= calendar.getActualMaximum(Calendar.DATE); i++) {
      JSONObject object = new JSONObject();
      calendar.set(Calendar.DATE, i);
      String startTime =
          getStringByTime(
              hourPattern,
              DateFormatUtil.getStartTimeByPeriod("daily", calendar.getTimeInMillis()));
      String endTime =
          getStringByTime(
              hourPattern, DateFormatUtil.getEndTimeByPeriod("daily", calendar.getTimeInMillis()));
      object.put("day", i);
      object.put("value", deviceMapper.selectCountByTime(startTime, endTime));
      result.add(object);
    }
    return result;
  }

  /** 查询泵站设备列表 */
  @Override
  public ResponseVo selectPumpDevice(Integer pageNo, Integer pageSize, String pumpDeviceType) {
    if (pageNo == null || pageNo <= 0) {
      pageNo = 1;
    }
    if (pageSize == null || pageSize <= 0) {
      pageSize = 15;
    }
    Page<DeviceVo> page = new Page<>(pageNo, pageSize);
    return ResponseVo.successWithData(deviceMapper.selectAllDevice(page, pumpDeviceType));
  }

  private ResponseVo duplicatedCodeInsertDevice(Device device) {
    // 经度，纬度
    String[] split = device.getGeometry().split(",");
    // 设备的Geo 后续修改
    device.setGeometry(null);
    device.setCreateTime(timeFormat(System.currentTimeMillis()));
    // 设置设备的更新时间
    device.setUpdateTime(timeFormat(System.currentTimeMillis()));
    if (deviceMapper.insert(device) > 0) {
      // 插入成功后修改geometry
      return deviceMapper.updateGeometry(device.getId(), split[0], split[1]) > 0
          ? ResponseVo.successWithData(device)
          : ResponseVo.SERVER_ERROR;
    } else {
      return ResponseVo.SERVER_ERROR;
    }
  }
}
